WELCOME, GUEST
Minimize
Blogger List

Steven Feuerstein Indicates Oracle ACE director status
PL/SQL Obsession

Guy Harrison Indicates Oracle ACE status
Database topics

Bert Scalzo Indicates Oracle ACE status
Toad for Oracle, Data Modeling, Benchmarking
Dan Hotka Indicates Oracle ACE director status
SQL Tuning & PL/SQL Tips

Valentin Baev
It's all about Toad

Ben Boise
Toad SC Discussions

Dan Clamage
SQL and PL/SQL

Kevin Dalton
Benchmark Factory

Peter Evans 
Business Intelligence, Data Integration, Cloud and Big Data

Vaclav Frolik  
Toad Data Modeler, Toad Extension for Eclipse

Devin Gallagher
Toad SC discussions

Stuart Hodgins
JProbe Discussions

Julie Hyman
Toad for Data Analysts

  Henrik "Mauritz" Johnson
Toad Tips & Tricks on the "other" Toads
  Mark Kurtz
Toad SC discussions
Daniel Norwood
Tips & Tricks on Toad Solutions
Amit Parikh
Toad for Oracle, Benchmark Factory,Quest Backup Reporter
Debbie Peabody
Toad Data Point
Gary Piper
Toad Reports Manager
John Pocknell
Toad Solutions
Jeff Podlasek
Toad for DB2
Kuljit Sangha
Toad SC discussions
Michael Sass 
Toad for DB2
Brad Wulf
Toad SC discussions
Richard To
SQL Optimization
  Toad Data Modeler Opens in a new window
Data Modeling
 
  Toad Higher Education
How Hi-Ed Uses Toad
  Real Automated Code Testing for Oracle
Quest Code Tester blog
  中文技术资料库
技术文章
 

Blogs

Toad World blogs are a mix of insightful how-tos from Quest experts as well as their commentary on experiences with new database technologies.  Have some views of your own to share?  Post your comments!  Note:  Comments are restricted to registered Toad World users.

Do you have a topic that you'd like discussed?  We'd love to hear from you.  Send us your idea for a blog topic.


Jan 13

Written by: QCTO Blog
Wednesday, January 13, 2010  RssIcon

Written by Finn Ellebaek Nielsen
Introduction
This blog post provides a short introduction to Continuous Integration (CI) and a description of how to integrate testing Oracle code with Quest Code Tester for Oracle (QCTO) in a CI environment.
Background
CI is the practice of early and frequent software integration through a so-called Build. A CI environment is typically configured to create a new Build once or several times a day but only when new or changed source code has been committed to the source code version control system.
A Build is typically broken down into the following subprocesses:
  • Compilation: Generation of scripts that will be used for execution of SQL scripts and compilation of PL/SQL source code. The script generation can be tricky as it needs to cater for dependencies amongst the database objects that have changed since the last build. Assuming that the sequence of the generated script is right, any compilation errors are fatal.
  • Test: Execution of automated tests at various levels, eg both unit and integration (component) tests. Any test cases failing are fatal.
  • Inspection: Inspection of the software, such as whether it conforms to established project standards for naming conventions, formatting, size of subprograms, code complexity, etc. Any violations are fatal.
  • Deployment: Optional deployment of the new build to a user acceptance test environment. Any deployment errors are fatal.
  • Documentation: Generation of the documentation based on comments in source code and overview written by developers, eg using Javadoc, NDoc, PlDoc etc.
  • Feedback: If any fatal errors have been encountered feedback must be generated and distributed, for instance in the form of an e-mail, an SMS or a red color to your Ambient Orb (a glass lamp you put in the office that through its color shows the state of the latest Build).

A dedicated CI server is typically set up with software that automates the CI process. Typically, this server will be configured to poll the source code version control system for changes every x seconds or once a day (in the evening). When the CI server detects a change it will start creating a new Build, covering all the components mentioned above.

You obtain the following benefits through adopting CI, among others:

  • Any code change that has been committed to the version control system is integrated as early as possible with the existing code and other changes. This is valuable feedback to the developer that made the change and if the change broke existing behavior this is detected as soon as possible, which results in higher software quality and lower cost.
  • The automated tests are automatically executed and you don't have to rely on developers or testers remembering to run the tests. Also, each developer will typically only run the unit tests, each covering one unit only and this is the first opportunity to run the integration (component) tests. This test level is necessary because it tests whether the components behave as expected when used together (aggregated behavior).
  • The software is automatically checked for compliance with project standards.
  • The documentation is automatically kept up to date.

Typically, Build software like make, Ant or Maven and CI software like CruiseControl and Continuum is used to obtain CI.

Since this blog is all about testing Oracle code with QCTO we shall focus on the testing aspect of CI only. Future blog posts may describe how to cover the other CI components with Oracle projects.

Automating QCTO

The CI server needs to be able to automate running the tests in QCTO and detect any unexpected outcome. Any CI server will be able to integrate most tools and programs through the following interface:

  • Run an executable or MS-DOS batch file (or UNIX/Linux shell script) with one or more parameters and wait for it to finish.
  • Interpret the exit code, standard output and standard error from the process after it has finished.

Basically, this can be achieved by two different means with QCTO, described in the following.

QCTO Command Line Interface

The command line interface to the QCTO executable facilitates a way of executing either all test cases in a test suite or a test definition through the following command line parameters:

  • /u=<username>: Username.
  • /p=<password>: Password.
  • /d=<tns_alias>: Oracle TNS alias.
  • /s=<test_suite_guid>: Test suite with given GUID is to be run.
  • /S=<test_suite_name>: Test suite with given name is to be run.
  • /t=<test_definition_guid>: Test definition with given GUID is to be run.
  • /T=<test_definition_name>: Test definition with given name is to be run.
  • /r: Run the given test suite provided with /s or /S, or the test definition provided with /t or /T.
  • /Close: Close after the tests have been run.
Example of a command line that executes the test suite called My_Test_Suite:
"C:\Program Files\Quest Software\Quest Code Tester for
Oracle\QuestCodeTesterOracle.exe" /u=qcto /p=qcto /d=test /S="My_Test_Suite" /r /Close

Unfortunately, using the command line interface has the following drawbacks:

  • The exit code from the QCTO executable is always 0, even if one or more test cases failed. You will need to investigate the test results (for the latest run) in the QCTO repository yourself or automate this with a SQL*Plus script.
  • You cannot name your test suites with spaces as the command line interface doesn't handle these correctly, even when you quote the test suite name with double quotes. An alternative is to use the GUID instead (with the /s option instead of /S).
  • You don't have full control over which test cases are executed: Either all test cases in a given suite or all test cases in a given test definition are executed.
  • You need to have the QCTO frontend installed on the CI server in order to be able to call it as part of the Build process.
QCTO API

The QCTO PL/SQL API provides an interface that is more useful for CI. Using the API you can control:

  • Which test cases that are to be executed:
    • All test cases in a given test suite (by name or GUID).
    • All test cases in a given test definition (by name or GUID).
    • Specific test cases (by name or GUID).
  • Present the outcome (including return values and output parameter values) and status on standard output.
  • Provide an exit code indicating failure to the CI server if any of the test cases failed.
The API is provided in the QU_TEST package, installed in the QCTO repository.
Test Suite

The following procedures in QU_TEST are provided for executing test suites:

  • RUN_SUITE_BY_GUID: Runs a given test suite through its GUID.
  • RUN_SUITE_BY_NAME: Runs a given test suite through its name.

Each of these is available in three different variants:

  • Simple overall status is returned in an output parameter.
  • Simple overall status is returned in an output parameter and another output parameter contains a ref cursor, through which you can get details of the test cases that were executed.
  • Simple overall status is returned in an output parameter and another output parameter contains a nested table, through which you can get details of the test cases that were executed.

The usage of these is described in detail in the QCTO on-line help.

Example:

declare
l_result varchar2(32767);
begin
qu_test.run_suite_by_name('My_Test_Suite', l_result);
dbms_output.put_line('l_result = ''' || l_result || '''');
end;
/
l_result = 'RUNTIME-ERROR'

PL/SQL procedure successfully completed.
which shows that this API is not very helpful when one or more test cases fail as it doesn't provide any details.
Test Definition

The following procedures are provided for executing test definitions:

  • RUN_TEST_FOR: Runs a given test definition and returns an overall status in an output parameter.
  • RUN_TEST_FOR2: Runs a given test definition, returns an overall status in an output parameter and returns a ref cursor useful for obtaining result details.
  • RUN_TEST_FOR3: Like RUN_TEST_FOR2 with additional information.
  • RUN_TEST_FOR4: Like RUN_TEST_FOR3 but providing a nested table instead of a ref cursor.

The usage of these is described in detail in the QCTO on-line help.

QCTO_CI

Let's look at an example that uses the most powerful of the QCTO test procedures -- RUN_TEST_FOR4. The example package QCTO_CI also shows how to use a few of the tables in the QCTO repository, namely:

  • QU_SUITE: Test suites.
  • QU_HARNESS: Test definitions.
  • QU_SUITE_HARNESS: Test suite/test definitions relationships.
  • QU_UNIT_TEST: Unit tests.
  • QU_TEST_CASE: Test cases.

The package contains two main functions, described in the following.

RUN_TEST_SUITE

Runs given QCTO test suite. Shows details about each test case on DBMS_OUTPUT. This function simply runs each test definition in the suite by calling RUN_TEST_DEFINITION for each, found through QU_SUITE, QU_SUITE_HARNESS and QU_HARNESS. It takes the following parameters:

  • Owner of program under test.
  • QCTO test suite name or GUID.
  • Comma-separated list of LIKE expressions for test case names or GUIDs for the test cases to run. LIKE is only supported with the names, not the GUIDs as that doesn't make sense. Default NULL, which means all test cases.
The number of test cases that failed is returned.
RUN_TEST_DEFINITION

Runs given QCTO test definition. Shows details about each test case on DBMS_OUTPUT. DBMS_OUTPUT is disabled while the test is running. This function takes the following parameters:

  • Owner of program under test.
  • QCTO test definition name or GUID.
  • Comma-separated list of LIKE expressions for test case names or GUIDs for the test cases to run. LIKE is only supported with the names, not the GUIDs as that doesn't make sense. Default NULL, which means all test cases.

The function basically does the following:

  • Finds test name/GUID through the GUID/name provided for the test definition.
  • Builds a list of GUIDs for the test cases that are to be run. This is resolved through the third parameter.
  • Calls RUN_TEST_FOR4.
  • Show the detailed results on DBMS_OUTPUT and count the number of test cases that failed.
  • Returns number of failed test cases.

COMMA_TO_TABLE

This function converts comma-separated values to an array containing the values. DBMS_UTILITY.COMMA_TO_TABLE does not work with values that are not legal SQL identifiers.

TABLE_TO_COMMA
Converts array elements to comma-separated values. DBMS_UTILITY.TABLE_TO_COMMA does not work with values that are not legal SQL identifiers.
Source Code
create or replace package qcto_ci as
/**
* Quest Code Tester for Oracle Continuous Integration interface.
*/

function run_test_suite(
p_program_owner in varchar2,
p_test_suite in varchar2,
p_test_cases in varchar2 := null
)
return integer;
function run_test_definition(
p_program_owner in varchar2,
p_test_definition in varchar2,
p_test_cases in varchar2 := null,
p_indent in pls_integer := 0
)
return integer;

function comma_to_table(p_s in varchar2)
return dbms_utility.uncl_array;
function table_to_comma(p_t in dbms_utility.uncl_array)
return varchar2;
end qcto_ci;
/

create or replace package body qcto_ci as
c_delimiter constant char(1) := ',';

/**
* Runs given Quest Code Tester for Oracle test suite. Shows details about each
* test case on DBMS_OUTPUT.
* @param p_program_owner
* Owner of program under test.
* @param p_test_suite
* QCTO test suite name or GUID.
* @param p_test_cases
* Comma-separated list of LIKE expressions for test case names
* or GUIDs for the test cases to run. LIKE is only supported
* with the names, not the GUIDs as that doesn't make sense.
* Default NULL, which means all test cases.
* @return Number of test cases that failed during the execution.
*/

function run_test_suite(
p_program_owner in varchar2,
p_test_suite in varchar2,
p_test_cases in varchar2 := null
)
return integer as

l_failures integer := 0;

begin
for s in (
select qs.name suite_name,
qs.universal_id
from qu_suite qs
where (
qs.universal_id = p_test_suite
or qs.name = p_test_suite
)
) loop
dbms_output.put_line('SUITE ' || s.suite_name);

for td in (
select qsh.harness_guid,
qh.program_name test_definition_name
from qu_suite_harness qsh,
qu_harness qh
where qsh.suite_guid = s.universal_id
and qh.universal_id = qsh.harness_guid
) loop
l_failures := l_failures + run_test_definition(
p_program_owner,
td.harness_guid /*td.test_definition_name*/,
p_test_cases,
1
);
end loop;

dbms_output.put_line(
'SUITE ' || s.suite_name || ': ' ||
l_failures || ' test case(s) failed'
);
end loop;

return l_failures;
end run_test_suite;

/**
* Runs given Quest Code Tester for Oracle test definition. Shows details about
* each test case on DBMS_OUTPUT. DBMS_OUTPUT is disabled while the test is
* running.
* @param p_program_owner
* Owner of program under test.
* @param p_test_definition
* QCTO test definition name or GUID.
* @param p_test_cases
* Comma-separated list of LIKE expressions for test case names
* or GUIDs for the test cases to run. LIKE is only supported
* with the names, not the GUIDs as that doesn't make sense.
* Default NULL, which means all test cases.
* @return Number of test cases that failed during the execution.
*/

function run_test_definition(
p_program_owner in varchar2,
p_test_definition in varchar2,
p_test_cases in varchar2 := null,
p_indent in pls_integer := 0
)
return integer as

l_result varchar2(100);
l_results qu_result_xp.last_run_results_api_nt;
l_failures integer := 0;
l_test_name varchar2(32767);
l_test_cases_csv varchar2(32767);
l_test_cases_array dbms_utility.uncl_array;
l_test_case_guid_array dbms_utility.uncl_array;
l_test_case_guid_csv varchar2(32767);
l_test_guid varchar2(100);
l_n binary_integer;

begin
if p_test_cases is not null then
-- Expand test case name filters by their GUIDs.

if p_test_definition like '{%}' then
l_test_guid := p_test_definition;

-- Find test name through GUID provided.
select program_name
into l_test_name
from qu_harness qh
where qh.universal_id = p_test_definition;
else
l_test_name := p_test_definition;

-- Find test GUID through name provided.
select qh.universal_id
into l_test_guid
from qu_harness qh
where qh.program_name = p_test_definition;
end if;

-- Make sure all test cases are GUIDs.
l_test_cases_array := comma_to_table(p_test_cases);
for i in
nvl(l_test_cases_array.first, 0) ..
nvl(l_test_cases_array.last, -1) loop
if l_test_cases_array(i) not like '{%}' then
for tc in (
select qtc.universal_id
from qu_unit_test qut,
qu_test_case qtc
where qut.harness_guid = l_test_guid
and qtc.unit_test_guid = qut.universal_id
and qtc.name like l_test_cases_array(i)
) loop
l_test_case_guid_array(l_test_case_guid_array.count + 1) :=
tc.universal_id;
end loop;
else
l_test_case_guid_array(l_test_case_guid_array.count + 1) :=
l_test_cases_array(i);
end if;
end loop;
l_test_case_guid_csv := table_to_comma(l_test_case_guid_array);
end if;

if p_test_cases is null or
p_test_cases is not null and l_test_case_guid_array.count > 0 then
-- Only run if we have been asked to run all test cases or if we have been
-- asked to run specific test cases and we found them.
qu_test.run_test_for4(
p_program_owner,
l_test_name,
l_result,
l_results,
null,
l_test_case_guid_csv,
',',
null
);
end if;

if l_results is not null then
for i in nvl(l_results.first, 0) .. nvl(l_results.last, -1) loop
if l_results(i).result_level not in ('INPUT', 'OUTPUT') and
l_results(i).result_status is not null then
-- Don't show input/output parameters but show the rest if they have been
-- executed (RESULT_STATUS not NULL).

dbms_output.put(
rpad (' ', (p_indent + l_results(i).h_level - 1) * 2) ||
l_results(i).result_level || ' ' ||
l_results(i).name ||
': '
);

if l_results(i).result_level in ('UNITTEST', 'TESTCASE') then
-- Only show start/stop for tests and test cases.
dbms_output.put(
'Started: ' ||
to_char(l_results(i).start_on, 'yyyy-mm-dd hh24:mi:ss') || ' ' ||
'Stopped: ' ||
to_char(l_results(i).end_on, 'yyyy-mm-dd hh24:mi:ss') || ' ' ||
'(' || round((l_results(i).end_on - l_results(i).start_on) * 86400) ||
's) '
);
end if;

dbms_output.put(l_results(i).result_status);
if l_results(i).result_status != 'SUCCESS' then
dbms_output.put(': ' || l_results(i).description);
end if;
dbms_output.put_line('');

if l_results(i).result_level = 'TESTCASE' and
l_results(i).result_status != 'SUCCESS' then
l_failures := l_failures + 1;
end if;
end if;
end loop;
end if;

dbms_output.put_line(
rpad(' ', p_indent * 2) || 'HARNESS ' ||
p_program_owner || '.' || l_test_name || ': ' ||
l_failures || ' test case(s) failed'
);

return l_failures;
end run_test_definition;

/**
* Converts comma-separated values to an array containing the values.
* DBMS_UTILITY.COMMA_TO_TABLE does not work with values that are not legal
* SQL identifiers.
* @param p_s Comma-separated values.
* @return Array of values.
*/

function comma_to_table(p_s in varchar2)
return dbms_utility.uncl_array as

i pls_integer;
j pls_integer;
l pls_integer;
l_result dbms_utility.uncl_array;

begin
i := 1;
j := instr(p_s, c_delimiter, i, 1);
if j = 0 then
j := l + 1;
end if;
l := nvl(length(p_s), 0);
while i <= l loop
l_result(l_result.count + 1) := substr(p_s, i, j - i);
i := j + 1;
j := instr(p_s, c_delimiter, i, 1);
if j = 0 then
j := l + 1;
end if;
end loop;

return l_result;
end comma_to_table;

/**
* Converts array elements to comma-separated values.
* DBMS_UTILITY.TABLE_TO_COMMA does not work with values that are not legal SQL
* identifiers.
* @param p_t Array of values.
* @return Comma-separated values.
*/

function table_to_comma(p_t in dbms_utility.uncl_array)
return varchar2 as

l_result varchar2(32767);

begin
for i in nvl(p_t.first, 0) .. nvl(p_t.last, -1) loop
l_result := l_result || p_t(i) || c_delimiter;
end loop;

return rtrim(l_result, c_delimiter);
end table_to_comma;
end qcto_ci;
/
Interfacing via SQL*Plus
By calling one of the two functions in the QCTO_CI package from a SQL*Plus script we can incorporate it into the Build process. Such a script run_qcto_test_definition.sql could look like the following (please note how we use the number of test cases that failed as the exit code):
set serveroutput on format truncated
set scan off
set define &
set scan on
set verify off
set feedback off

variable l_failures number

begin
  :l_failures := 1;
end;
/

begin
  :l_failures := qcto_ci.run_test_definition('&&1', '&&2', '&&3');
end;
/

exit :l_failures

The script takes 3 parameters corresponding to the parameters of the function. The SQL*Plus script could in turn be called from an MS-DOS batch script run_qcto_test_definition.bat (assuming that this also takes 3 parameters):

call sqlplus -s <user>/<password>@<tns> @run_qcto_test_definition.sql "%1" "%2" "%3"
exit %ERRORLEVEL%

This is the MS-DOS batch script that would be called directly from the CI server. If you need to call this through cmd.exe (eg when you execute it from a Java environment) you will have to escape the percent character with an extra one in case you use that for the LIKE expressions as they would be regarded as references to environment variables. Example of how to call a test definition for the TEST_DATA_TYPES package owned by SCOTT and only executing the test cases with names matching '%BLOB%', '%CLOB%' or '%BOOLEAN%':

run_qcto_test_definition.bat SCOTT TEST_DATA_TYPES "%%BLOB%%,%%CLOB%%,%%BOOLEAN%%"
Output
The output produced can easily be tailored to your requirements in terms of details and format (eg HTML or XML). The source code provided in this blog post produces a plain output as illustrated by the following example:
set serveroutput on format truncated

begin
dbms_output.put_line(
qcto_ci.run_test_definition(
'SCOTT',
'TEST_DATA_TYPES',
'%BLOB%,%CLOB%,%BOOLEAN%'
)
);
end;
/
HARNESS SCOTT.TEST_DATA_TYPES: FAILURE: Test failed at this level.
 UNITTEST TEST_BLOB: Started: 2010-01-13 19:49:43 Stopped: 2010-01-13 19:49:43 (0s) SUCCESS
    TESTCASE TEST_BLOB S: Started: 2010-01-13 19:49:43 Stopped: 2010-01-13 19:49:43 (0s) SUCCESS
      OUTCOME Scalar is equal to the expected value?: SUCCESS
      OUTCOME Value modified by the program is NULL?: SUCCESS
 UNITTEST TEST_BOOLEAN: Started: 2010-01-13 19:49:43 Stopped: 2010-01-13 19:49:43 (0s) FAILURE: Test failed at this level.
    TESTCASE TEST_BOOLEAN S: Started: 2010-01-13 19:49:43 Stopped: 2010-01-13 19:49:43 (0s) SUCCESS
      OUTCOME Does the Boolean expression evaluate to FALSE?: SUCCESS
      OUTARG B2: SUCCESS
      OUTARG [Function return value]: SUCCESS
      OUTCOME Value modified by the program is NULL?: SUCCESS
    TESTCASE TEST_BOOLEAN F: Started: 2010-01-13 19:49:43 Stopped: 2010-01-13 19:49:43 (0s) FAILURE: Test failed at this level.
      OUTCOME Does the Boolean expression evaluate to TRUE?: SUCCESS
      OUTARG [Function return value]: SUCCESS
      OUTCOME Does the Boolean expression evaluate to TRUE?: FAILURE: Expression evaluates to NULL.
      OUTARG B2: SUCCESS
 UNITTEST TEST_CLOB: Started: 2010-01-13 19:49:43 Stopped: 2010-01-13 19:49:43 (0s) SUCCESS
    TESTCASE TEST_CLOB S: Started: 2010-01-13 19:49:43 Stopped: 2010-01-13 19:49:43 (0s) SUCCESS
      OUTARG S: SUCCESS
      OUTARG [Function return value]: SUCCESS
      OUTCOME Scalar is equal to the expected value?: SUCCESS
      OUTCOME Scalar is equal to the expected value?: SUCCESS
    TESTCASE TEST_CLOB 32000: Started: 2010-01-13 19:49:43 Stopped: 2010-01-13 19:49:43 (0s) SUCCESS
      OUTARG [Function return value]: SUCCESS
      OUTCOME Scalar is equal to the expected value?: SUCCESS
      OUTARG S: SUCCESS
      OUTCOME Scalar is equal to the expected value?: SUCCESS
HARNESS SCOTT.TEST_DATA_TYPES: 1 test case(s) failed
1

PL/SQL procedure successfully complet
ed.
Naming Conventions

Through a naming convention you can categorize your tests into the test level they belong to, for instance:

  • Unit test case names are prefixed with a U.
  • Integration/component test case names are prefixed with an I or a C.
  • System test cases are prefixed with an S.

Such a naming convention would enable you to run all the unit and integration tests in a given test definition through a call like:

begin
  dbms_output.put_line(
    qcto_ci.run_test_definition(
      'SCOTT',
      'TEST_DATA_TYPES',
      'U%,I%'
    )
  );
end;
/

References

  • Continuous Integration: Improving Software Quality and Reducing Risk by Paul M. Duvall, Steve Matyas and Andrew Glover, Addison Wesley, 2007. ISBN 978-0321336385.
  • Wikipedia: http://en.wikipedia.org/wiki/Continuous_integration.
  • Ambient Orb: http://www.ambientdevices.com/cat/orb/orborder.html.

Continuous Integration
http://www.toadworld.com/Blogs/tabid/67/EntryId/493/Continuous-Integration.aspx
del.icio.usFacebookDiggGoogleLive BookmarksNewsvineStumbleUponTechnoratiYahooDotNetKicks

6 comment(s) so far...


Gravatar

Re: Continuous Integration

Update:

For CT 1.9 the datatype changed from DATE to TIMESTAMP in so for 1.9 you have to change

'(' || round((l_results(i).end_on - l_results(i).start_on) * 86400) || 's) '

to

'(' || to_char(extract(second from(l_results(i).end_on - l_results(i).start_on)), 'fm999g999g990d00') || 's) '

Regards

Finn

By Anonymous on   Tuesday, November 30, 2010
Gravatar

Re: Continuous Integration

Using Beta 2, after rebuild of back end, Q_SUITE_HARNESS table not found. Also, is there a download package for all this stuff somewhere? I can't seem to find it again.

By Anonymous on   Saturday, December 04, 2010
Gravatar

Re: Continuous Integration

Do you mean QU_SUITE_HARNESS? All the source code for this blog post is shown above, no need for other downloads.

Just a word of caution: The source code shown here (prefixed with QCTO) is not supported by Quest. Only the source code prefixed with QU is supported with the tool.

By FinnEllebaekNielsen on   Sunday, December 05, 2010
Gravatar

Re: Continuous Integration: run for test_owner=T?

Hi, Finn

Thanks for your run_test_for4 example. I've been using this as the basis for my CI scripts. At first I was confused about the p_program_owner argument and mistakenly used the name of the *test owner* schema (i.e. HARNESS_OWNER). In my case, test definitions belong to one schema=T, but the code-under-test belongs to a different schema=C. Thus, in my case, run_test_for4 must be invoked with p_program_owner=C.

Which is actually a bit unfortunate. It would more convenient to indicate the tests to run via the test owner schema=T. Do you know if there is an API to do this?

Regards,
Kerry

By Anonymous on   Tuesday, January 04, 2011
Gravatar

Re: Continuous Integration

Hi Matthijs

Are you able to run that test definition from the QCTO GUI?

Can QUTE see CB.BOL_UTIL?

What happens if you call qcto_ci.run_test_definition('CB', 'BOL_UTIL', '{%}')?

Best regards

________________________

Finn Ellebaek Nielsen
Oracle Test Coach
oracletesting.com

By FinnEllebaekNielsen on   Friday, September 02, 2011
Gravatar

Re: Continuous Integration

Hi Lourens

Thanks a lot for pointing this out. Yet another major change in CT 2.0, sigh :-).

I'll have a look at this soon when I have more time. The query above doesn't handle suite order and I'm not sure it handles suites of suites, suites of test definitions, suites of test cases etc so I'll have a thorough look.

Cheers

________________________

Finn Ellebaek Nielsen
Oracle Test Coach
oracletesting.com

By FinnEllebaekNielsen on   Tuesday, September 20, 2011
Search Blog Entries
 
Blog Archives
 
Archive
<May 2013>
SunMonTueWedThuFriSat
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678
Monthly
April, 2013 (13)
March, 2013 (10)
February, 2013 (5)
January, 2013 (7)
December, 2012 (6)
November, 2012 (10)
October, 2012 (8)
September, 2012 (6)
August, 2012 (8)
July, 2012 (8)
June, 2012 (12)
May, 2012 (21)
April, 2012 (10)
March, 2012 (16)
February, 2012 (19)
January, 2012 (20)
December, 2011 (19)
November, 2011 (14)
October, 2011 (12)
September, 2011 (17)
August, 2011 (15)
July, 2011 (16)
June, 2011 (13)
May, 2011 (15)
April, 2011 (8)
March, 2011 (21)
February, 2011 (17)
January, 2011 (16)
December, 2010 (13)
November, 2010 (13)
October, 2010 (7)
September, 2010 (15)
August, 2010 (11)
July, 2010 (13)
June, 2010 (12)
May, 2010 (14)
April, 2010 (12)
March, 2010 (13)
February, 2010 (12)
January, 2010 (7)
December, 2009 (10)
November, 2009 (12)
October, 2009 (15)
September, 2009 (18)
August, 2009 (13)
July, 2009 (23)
June, 2009 (14)
May, 2009 (17)
April, 2009 (7)
March, 2009 (14)
February, 2009 (7)
January, 2009 (12)
December, 2008 (7)
November, 2008 (11)
October, 2008 (19)
September, 2008 (14)
August, 2008 (11)
July, 2008 (14)
June, 2008 (19)
May, 2008 (12)
April, 2008 (18)
March, 2008 (13)
February, 2008 (8)
January, 2008 (7)
December, 2007 (5)
November, 2007 (8)
October, 2007 (13)
September, 2007 (13)
August, 2007 (16)
July, 2007 (11)
June, 2007 (6)
May, 2007 (5)
April, 2007 (5)
March, 2007 (8)
February, 2007 (6)
January, 2007 (6)
December, 2006 (5)
November, 2006 (8)
October, 2006 (4)
August, 2006 (3)